package top.maof.book.spider.runtime;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import top.maof.book.config.RestTemplateConfig;
import top.maof.book.model.Chapter;
import top.maof.book.model.Contents;
import top.maof.book.model.Web;
import top.maof.book.service.ContentsService;
import top.maof.book.utils.URLUtils;

import java.util.LinkedHashSet;
import java.util.Set;

@Component
@Slf4j
public class BookSpider {
    @Autowired
    @Qualifier("restTemplate1")
    RestTemplate restTemplate_utf8;

    @Autowired
    @Qualifier("restTemplate2")
    RestTemplate restTemplate_gbk;

    @Autowired
    @Qualifier("restTemplate3")
    RestTemplate restTemplate_gb2312;


    public Set<Pair> contents(String url, Web web) throws Exception {
        log.info(url);
        log.info(web.getSite());
        String s = URLUtils.changeDomain(web.getUrl(), url);
        String html = this.getHtml(s, web.getCharset());
        return this.contents(html, s, web.getContentsSelect());
    }

    /**
     * 解析原始页面,获取原始章节列表,返回set集合并去重
     *
     * @param html
     * @param baseUri
     * @param select
     * @return
     */
    public Set<Pair> contents(String html, String baseUri, String select) throws Exception {
        Elements elements = Jsoup.parse(html).select(select);
        Set<Pair> set = new LinkedHashSet(256);
        if (elements != null) {
            for (Element e : elements) {
                // e.setBaseUri(baseUri);
                //e.attr("abs:href")
                Pair pair = new Pair(URLUtils.completeUrl(baseUri, e.attr("href")), e.text());
                if (set.contains(pair)) {
                    set.remove(pair);
                }
                set.add(pair);
            }
        }
        return set;
    }

    /**
     * 将章节列表json化
     *
     * @param contents
     * @param web
     * @return
     */

    public String content(Contents contents, Web web) throws Exception {
        return JSON.toJSONString(contents(contents.getUrl(), web));
    }

    public String content(String url, Web web) throws Exception {
        return JSON.toJSONString(contents(url, web));
    }


    private HttpHeaders requestHeaders;

    private HttpEntity<String> requestEntity;

    {
        requestHeaders = new HttpHeaders();
        requestHeaders.add("User-Agent",
                "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 Edg/87.0.664.66");
        requestEntity = new HttpEntity<String>(null, requestHeaders);
    }

    /**
     * 抓取原始页面
     *
     * @param url
     * @param charset
     * @return
     */
    public String getHtml(String url, String charset) throws Exception {
        switch (charset) {
            case "utf-8":
                return restTemplate_utf8.exchange(url, HttpMethod.GET, requestEntity, String.class).getBody();
            case "gbk":
                return restTemplate_gbk.exchange(url, HttpMethod.GET, requestEntity, String.class).getBody();
            case "gb2312":
                return restTemplate_gb2312.exchange(url, HttpMethod.GET, requestEntity, String.class).getBody();
            default:
                return RestTemplateConfig.restTemplate(charset).exchange(url, HttpMethod.GET, requestEntity, String.class).getBody();
        }
    }

    @Autowired
    ContentsService contentsService;


    /**
     * 解析页面,返回小说具体章节
     *
     * @param url
     * @param web
     * @return
     */
    public Chapter chapter(String url, Web web) throws Exception {
        String html = this.getHtml(url, web.getCharset());
        Chapter chapter = new Chapter();
        Document parse = Jsoup.parse(html);
        // 章节内容
        chapter.setContent(parse.select(web.getChapterContentSelect()).toString());
        // 下一章url地址
        Elements nexts = parse.select(web.getChapterNextSelect());
        if (nexts.size() > 0) {
            Element next = nexts.get(0);
            //next.setBaseUri(url);
            String nextHref = URLUtils.completeUrl(url, next.attr("href"));
            if (contentsService.findByUrl(nextHref) == null)
                chapter.setNextUrl(nextHref);
        }

        //上一章url地址
        Elements pres = parse.select(web.getChapterPreviousSelect());
        if (pres.size() > 0) {
            // previous.setBaseUri(url);
            Element previous = pres.get(0);
            String preHref = URLUtils.completeUrl(url, previous.attr("href"));
            if (contentsService.findByUrl(preHref) == null)
                chapter.setPreviousUrl(preHref);
        }
        // 本章url地址
        chapter.setUrl(url);
        // 章节标题
        chapter.setTitle(parse.select(web.getChapterTitleSelect()).text());

        return chapter;
    }

}
